package com.bindatax.core.task;

import com.bindatax.core.config.SysConfig;
import com.bindatax.core.log.LogOutInterface;
import com.bindatax.core.log.LogOutManager;
import com.bindatax.core.task.event.EventType;
import com.bindatax.core.util.StringUtils;

import java.util.*;
import java.util.concurrent.*;

public class DataTaskPool {

    private final static LogOutInterface LOG = LogOutManager.get();
    private ExecutorService executorService;
    private final List<Future<DataTask>> futureList = new ArrayList<Future<DataTask>>();
    private boolean stopAllTask = false;

    /**
     * 创建线程池
     *
     * @param
     * @return void
     * @author ChenZhenQin
     * @date 15:59 2022/2/23
     * @version V1.0.0
     */

    public DataTaskPool() {
        // 创建一个自定义的ThreadFactory
        ThreadFactory customThreadFactory = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                String name = "DataTask-" + System.currentTimeMillis();
                Thread thread = new Thread(r,name);
                return thread;
            }
        };
        int corePoolSize = SysConfig.getConcurrencyQueryMinSize();
        int maximumPoolSize = corePoolSize * 2;
        executorService = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(),
                //Executors.defaultThreadFactory(),
                customThreadFactory,
                new ThreadPoolExecutor.AbortPolicy()
        );
    }

    /**
     * 放入单个任务
     *
     * @param dataTask
     * @return void
     * @author ChenZhenQin
     * @date 15:59 2022/2/23
     * @version V1.0.0
     */
    public void addDataTask(DataTask dataTask) {
        if (stopAllTask) {
            LOG.warn("任务执行组已停止！不能再加入任务！");
            return;
        }
        LOG.info("加入任务：" + dataTask);
        futureList.add(executorService.submit(dataTask));
    }

    /**
     * 等待多线程 结束
     *
     * @param
     * @return void
     * @author ChenZhenQin
     * @date 16:00 2022/2/23
     * @version V1.0.0
     */
    public void waitDataTaskFinished() {
        executorService.shutdown();
        while (true) {
            if (futureList.isEmpty()) {
                return;
            }
            Iterator<Future<DataTask>> iterator = futureList.iterator();
            while (iterator.hasNext()) {
                Future<DataTask> future = iterator.next();
                if (future.isDone()) {
                    try {
                        DataTask task = future.get();
                        // 执行销毁事件
                        task.exeEvent(EventType.TASK_DESTROYED);
                    } catch (Exception e) {
                        LOG.info("任务结果异常：" + StringUtils.getExceptionInfo(e));
                    } finally {
                        iterator.remove();
                    }
                }
            }
            if (stopAllTask && futureList.isEmpty()) {
                return;
            }
        }
    }

    public synchronized void stopAllTask() {
        stopAllTask = true;
        if (futureList.isEmpty()) {
            return;
        }
        for (Future<DataTask> future : futureList) {
            try {
                DataTask task = future.get();
                if (!future.isDone()) {
                    task.stopTask();
                }
                future.cancel(true);
            } catch (Exception e) {
                LOG.info("任务停止异常：" + StringUtils.getExceptionInfo(e));
            }
        }
    }
}
